#include "base/channel.h"
#include "base/eventloop.h"
#include "base/log.h"
#include "base/config.h"

#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>

#include "base/logfile.h"
namespace net_tools::base
{
  Logfile::Logfile(std::string app_name, net_tools::Eventloop *eventloop, FILE *file_stream)
      : app_name_(std::move(app_name)),
        eventloop_(eventloop),
        pid_(getpid()),
        index_(0),
        tm_buf{0},
        filename_(),
        fd_stream_(nullptr),
        logbuffer_(this, eventloop_),
        use_file_(false),
        write_size_(0)
  {
    if (file_stream)
    {
      Setstream(file_stream);
    }
    else
    {
      Use_file_flush_file();
    }
  };
  Logfile::~Logfile(){};
  //如果之前没有使用file 则使用 否则滚动日志
  void Logfile::Use_file_flush_file()
  {
    if (!use_file_)
    {
      Creatfile();
    }
    else
    {
      Rollfile();
    }
  };
  // 如果之前使用file 则关闭 设为新的FILE
  void Logfile::Setstream(FILE *stream)
  {
    logbuffer_.Set_fd(stream);
    int flag = access(filename_.c_str(), F_OK);
    if (flag == 0)
    {
      Endfile();
    }
    fd_stream_ = stream;
  };
  void Logfile::Flush()
  {
    if (use_file_)
    {
      write_size_ += logbuffer_.Flush();
      if (write_size_ >= _C::SET_LOG_SET_FILE_MAX_SIZE)
      {
        Rollfile();
      }
    }
    else
    {
      logbuffer_.Flush();
    }
  };
  void Logfile::Output(void *address, short int len)
  {
    logbuffer_.Output(address, len);
  };
  void Logfile::Creatfile()
  {
    gettimeofday(&begin_time_, NULL);
    struct tm tm_time_;
    localtime_r(&begin_time_.tv_sec, &tm_time_);
    strftime(tm_buf, 128, "%F-%T--", &tm_time_);
    filename_ = app_name_ + ":" + std::to_string(pid_) + ":" + tm_buf;
    NT_LOG_INFO << "Change Log file to:" << filename_ << NT_LOG_ENDL;
    fd_stream_ = fopen(filename_.c_str(), "w");
    write_size_ = 0;
    use_file_ = true;
    logbuffer_.Set_fd(fd_stream_);
  };
  void Logfile::Endfile()
  {
    fflush(fd_stream_);
    gettimeofday(&end_time_, NULL);
    struct tm tm_time_;
    localtime_r(&end_time_.tv_sec, &tm_time_);
    strftime(tm_buf, 128, "%F-%T", &tm_time_);
    std::string old = filename_;
    filename_ += tm_buf;
    filename_ += "_" + std::to_string(index_);
    logbuffer_.Set_fd(stderr);
    use_file_ = false;
    fclose(fd_stream_);
    rename(old.c_str(), filename_.c_str());
    filename_.clear();
    ++index_;
  };
  void Logfile::Rollfile()
  {
    NT_LOG_INFO << "Roll Log file" << NT_LOG_ENDL;
    fflush(fd_stream_);
    gettimeofday(&end_time_, NULL);
    begin_time_.tv_sec = end_time_.tv_sec;
    struct tm tm_;
    localtime_r(&end_time_.tv_sec, &tm_);
    //创建新的文件
    strftime(tm_buf, 128, "%F-%T--", &tm_);
    std::string new_filename = app_name_ + ":" + std::to_string(pid_) + ":" + tm_buf;
    FILE *new_stream = fopen(new_filename.c_str(), "w");
    write_size_ = 0;
    logbuffer_.Set_fd(new_stream);
    //改名
    std::string old = filename_;
    strftime(tm_buf, 128, "%F-%T", &tm_);
    filename_ += tm_buf;
    filename_ += "_" + std::to_string(index_);
    ++index_;
    fclose(fd_stream_);
    rename(old.c_str(), filename_.c_str());
    //更新
    filename_ = std::move(new_filename);
    fd_stream_ = new_stream;
  };

} // namespace net_tools::base
